import http.server
import socketserver
import os
import sys
from urllib.parse import quote, unquote
from io import BytesIO

PORT = 9000

if len(sys.argv) > 1:
    directory = sys.argv[1]
    if not os.path.isdir(directory):
        print(f"错误：{directory} 不是一个有效的目录。")
        sys.exit(1)
    os.chdir(directory)


class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    def log_message(self, format, *args):
        """重写日志方法以支持中文显示"""
        # 使用UTF-8编码处理日志消息
        message = format % args
        try:
            # 尝试解码URL编码的中文字符
            if '%' in message:
                parts = message.split('"')
                if len(parts) >= 2:
                    url_part = parts[1]
                    decoded_url = unquote(url_part)
                    message = message.replace(url_part, decoded_url)
        except:
            pass
        
        # 输出到控制台
        print(message)
    
    def list_directory(self, path):
        try:
            file_list = os.listdir(path)
        except OSError:
            self.send_error(404, "没有权限访问该目录")
            return None

        file_list.sort(key=lambda a: a.lower())
        r = []

        # 生成返回上一层目录的链接
        parent_path = os.path.dirname(path)
        if parent_path != path:
            relative_parent = os.path.relpath(parent_path, os.getcwd()).replace('\\', '/')
            link = '/' + quote(relative_parent, safe='/%')
            if relative_parent == '.':
                link = '/'
            elif not link.endswith('/'):
                link = link + '/'
            r.append(f'<li><a href="{link}">../</a></li>')

        for name in file_list:
            full_name = os.path.join(path, name)
            display_name = link_name = name
            if os.path.isdir(full_name):
                display_name = name + "/"
                link_name = name + "/"
            if os.path.islink(full_name):
                display_name = name + "@"
            relative_path = os.path.relpath(full_name, os.getcwd()).replace('\\', '/')
            link = '/' + quote(relative_path, safe='/%')
            if os.path.isdir(full_name) and not link.endswith('/'):
                link = link + '/'
            r.append(f'<li><a href="{link}">{display_name}</a></li>')

        # 使用UTF-8编码
        title = f'目录列表： {unquote(self.path, "utf-8").rstrip("/")}'
        header = f'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">\n' \
                 f'<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=utf-8">\n' \
                 f'<title>{title}</title>\n</head>\n<body>\n'
        footer = '</body>\n</html>\n'
        content = '\n'.join([header, '<ul>\n' + '\n'.join(r) + '</ul>\n', footer])
        encoded = content.encode('utf-8', 'surrogateescape')

        f = BytesIO()
        f.write(encoded)
        f.seek(0)

        self.send_response(200)
        self.send_header("Content-type", "text/html; charset=utf-8")
        self.send_header("Content-Length", str(len(encoded)))
        self.end_headers()
        return f

    def translate_path(self, path):
        path = path.split('?', 1)[0]
        path = path.split('#', 1)[0]
        path = unquote(path)
        path = path.lstrip('/')
        words = path.split('/')
        words = filter(None, words)
        path = os.getcwd()
        for word in words:
            if word in (os.curdir, os.pardir):
                continue
            path = os.path.join(path, word)
        return path


Handler = CustomHTTPRequestHandler

with socketserver.TCPServer(("", PORT), Handler) as httpd:
    print(f"服务器正在运行，端口号为 {PORT}，共享目录为 {os.getcwd()}")
    httpd.serve_forever()
    
